// 操作符、整型提升、操作符的优先级

#include<stdio.h>
#include<string.h>
//---------------------------------------------小节分割线--------------------------------------------
// 移位操作符
//int main()
//{
//	int a = -10; // 4个字节，占32个比特位
//	// 00000000 00000000 00000000 00001010
//	int b = a << 1; // 将a的二进制位向左移动一位
//	// 00000000 00000000 00000000 00010100
//	// 左移操作符：左边丢弃，右边补0
//	int c = a >> 1;
//	// 00000000 00000000 00000000 00000101
//	// 右移操作符：算数右移而不是逻辑右移。左边用原该值的符号位填充，右边丢弃
//	printf("b = %d\n", b);
//	printf("c = %d\n",c);
//	return 0;
//}
//---------------小分割线 >.< --------------------
// 位操作符，都得是整型
//int main()
//{
//	int num1 = 3; // 00000000 00000000 00000000 00000011
//	int num2 = 5; // 00000000 00000000 00000000 00000101
//	printf("%d\n", num1 & num2);  //按位与，二进制位中都是1才是1
//	printf("%d\n", num1 | num2);  //按位或，二进制位中有1就是1
//	printf("%d\n", num1 ^ num2);  //按位异或，二进制位相同为0，不同为1
//	return 0;
//}
//---------------小分割线 >.< --------------------
// sizeof也属于单目操作符
// #include <stdio.h>
// void test1(int arr[])
// {
//  printf("%d\n", sizeof(arr));//(2)
// }
// void test2(char ch[])
// {
//  printf("%d\n", sizeof(ch));//(4)
// }
// int main()
// {
//  int arr[10] = {0};
//  char ch[10] = {0};
//  printf("%d\n", sizeof(arr));//(1)
//  printf("%d\n", sizeof(ch));//(3)
//  test1(arr);
//  test2(ch);
//  return 0;
// }
//---------------小分割线 >.< --------------------
// 结构体的访问  . 和 ->  的访问
//struct Stu
//{
//	char name[10];
//	int age;
//	char sex[5];
//	double score;
//};
//
//int main()
//{
//	struct Stu stu1 = { "张三" , 20, "男", 62.34};
//	struct Stu* pStu1 = &stu1;//结构成员访问，这里说明pStu是指向stu的一个指针，数据类型是struct Stu
//	
//	//printf("姓名：%s\n", stu1.name); // 结构体名称.成员名
//	//printf("年龄：%d\n", stu1.age);
//	//printf("性别：%s\n", stu1.sex);
//	//printf("分数：%.2f\n", stu1.score);
//
//	//printf("姓名：%s\n", (*pStu1).name); // (*结构体指针).成员名
//	//printf("年龄：%d\n", (*pStu1).age);
//	//printf("性别：%s\n", (*pStu1).sex);
//	//printf("分数：%.2f\n", (*pStu1).score);
//
//	printf("姓名：%s\n", pStu1->name); // 结构体指针->成员名
//	printf("年龄：%d\n", pStu1->age);
//	printf("性别：%s\n", pStu1->sex);
//	printf("分数：%.2f\n", pStu1->score);
//	// 三种不同的访问结构体实例的方法
//	return 0;
//}
//---------------------------------------------小节分割线--------------------------------------------
// 整型提升
//int main()
//{
//	char a = 3; // 如果写成32位，就是00000000 00000000 00000000 00000011，发生截断，只存00000011
//	char b = 127; // 如果写成32位，就是00000000 00000000 00000000 01111111，发生截断，只存01111111
//	char c = a + b;
//	printf("%d\n", c);
//	// 这里a和b都是char类型，都没有达到一个int的大小，这里就会发生整型提升
//	// 整形提升是按照变量的数据类型的符号位来提升的，正数补0，负数补1，如果是无符号类型，高位直接补0
//	// a截断后的00000011，在进入cpu时会发生 整型提升 ，自动补全到32位，变成00000000 00000000 00000000 00000011
//	// 同理， b截断后的01111111，在进入cpu时会自动补全到32位，变成00000000 00000000 00000000 01111111
//	// 相加后变成了00000000 00000000 00000000 10000010
//	// 但是一个char只能存放8个比特位，于是10000010就存入了c中
//	// 
//	// 在输出c的过程中，又发生一次 整型提升 ，给前面全部补了1
//	// 
//	// 由于内存中数据存储都是补码，10000010被当作了负数。
//	// 原码     →符号位以外取反→       反码      →      加1     →    补码
//	// 补码     →     减1      →       反码      →符号位以外取反→    原码 
//	// 同理，将10000010作为补码反向推回原码
//	// 11111111 11111111 11111111 10000010 补码
//	// 11111111 11111111 11111111 10000001 反码
//	// 10000000 00000000 00000000 01111110 原码
//	// 于是输出结果就当作是-126了
//	return 0;
//}
//---------------小分割线 >.< --------------------
// 整型提升例子1
//int main()
//{
//	char a = 0xb6;
//	short b = 0xb600;
//	int c = 0xb6000000;
//	if (a == 0xb6)
//		printf("a"); // char不到一个int的大小，需要发生整型提升
//	if (b == 0xb600)
//		printf("b"); // short不到一个int的大小，需要发生整型提升
//	if (c == 0xb6000000)
//		printf("c"); // 没有发生整型提升
//	return 0;
//}
//---------------小分割线 >.< --------------------
// 整型提升例子2
//int main()
//{
//	char c = 1;
//	printf("%u\n", sizeof(c)); // 
//	printf("%u\n", sizeof(+c)); // 
//	printf("%u\n", sizeof(-c)); // 
//	return 0;
//}
//---------------------------------------------小节分割线--------------------------------------------
// 算术转换
// 以下的数据类型，从下向上转换
// 例：一个int和一个float相加，int会被转化成float
//long double
//double
//float
//unsigned long int
//long int
//unsigned int
//int
//---------------------------------------------小节分割线--------------------------------------------
// 操作符的优先级
// 见课件 第5节-操作符详解.pdf中的12.3
// 1.越靠前优先级越高
// 2.优先级相同时，考虑结合性， L-R 表示从左向右结合先算左边，R-L 同理
// 重点：
// 需要通过语句能确定唯一的计算路径
// 如果在不同的编译环境下，因为不同的计算路径会出现不同的结果
// 那说明写出来的代码是有问题的
// 
// 